package com.easycode.devtool.service;


import com.easycode.devtool.domain.DataBaseModel;
import com.easycode.devtool.domain.FieldModel;
import com.easycode.devtool.domain.TableModel;
import com.easycode.devtool.util.DateUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * Created by yangyanchen on 2017/5/22
 * Copyright © 2016 －2017 深圳布谷鸟信息技术有限公司
 */
public class Mapper2Service {



    private static String generateStmt(int stmtType,String tableName)
    {
        //备注：1:添加,2:删除,3:修改,4:单个条件查询,5:分页查询(带总数)
        StringBuffer buffer = new StringBuffer("_db.createConnection(_connectstring);\n");
        switch (stmtType)
        {
            case 1:
                buffer.append("_db.createCommand(\"cp_" +
                         tableName+
                        "_addRecord\", DBCommandType.StoreProcedure);\n");
                break;
            case 2:
                buffer.append("_db.createCommand(\"cp_" +
                        tableName+
                        "_deleteRecord\", DBCommandType.StoreProcedure);\n");
                break;
            case 3:
                buffer.append("_db.createCommand(\"cp_" +
                        tableName+
                        "_updateRecord\", DBCommandType.StoreProcedure);\n");
                break;
            case 4:
                buffer.append("_db.createCommand(\"cp_" +
                        tableName+
                        "_getRecordById\", DBCommandType.StoreProcedure);\n");
                break;
            case 5:
                buffer.append("_db.createCommand(\"cp_" +
                        tableName+
                        "_getRecords\", DBCommandType.StoreProcedure);\n");
                break;
        }
        return buffer.toString();
    }

    private static String generateParameter(List<FieldModel> list, int stmtType)
    {
        StringBuffer buffer = new StringBuffer();
        Iterator iterator = list.iterator();
        while (iterator.hasNext())
        {
            FieldModel fieldModel = (FieldModel) iterator.next();
            if("id".equalsIgnoreCase(fieldModel.getFieldName()) && stmtType == 1)
            {
                continue;
            }
            if("create_time".equalsIgnoreCase(fieldModel.getFieldName()))
            {
                continue;
            }
            if("delete_state".equalsIgnoreCase(fieldModel.getFieldName()))
            {
                continue;
            }
            if("update_time".equalsIgnoreCase(fieldModel.getFieldName()))
            {
                continue;
            }
            buffer.append("_db.addParameter(\"")
                    .append(fieldModel.getFieldName())
                    .append("_value\",")
                    .append("domain.get")
                    .append(upperCaseField(fieldModel.getFieldName()))
                    .append("());\n");
        }
        return buffer.toString();
    }

    private static String upperCaseField(String fieldName)
    {
        if(fieldName.equalsIgnoreCase("id"))
        {
            return "Id";
        }
        fieldName = fieldName.replace(fieldName.substring(0, 1), fieldName.substring(0, 1).toUpperCase());
        String[] temp = fieldName.split("_");
        String result = "";
        for (int i = 0; i < temp.length; i++) {
            temp[i] = temp[i].replace(temp[i].substring(0, 1), temp[i].substring(0, 1).toUpperCase());
            result += temp[i];
        }
        return result;
    }

    private static String generateOutPutStmt()
    {
        StringBuffer buffer = new StringBuffer();
         buffer.append("_db.addParameter(\"SPReturnValue\", ParameterDirection.Output);\n");
         buffer.append("_db.executeNonQuery();\n");
         buffer.append("return CommonUtils.getIntValue(_db.getParamValue(\"SPReturnValue\"))>0;\n");
         return buffer.toString();
    }

    private static String generateResult(List<FieldModel> list)
    {
        StringBuffer buffer = new StringBuffer();
        Iterator iterator = list.iterator();
        while (iterator.hasNext())
        {
            FieldModel model = (FieldModel)iterator.next();
            buffer.append("domain.set")
                    .append(upperCaseField(model.getFieldName()))
                    .append("(")
                    .append(inferType(model.getFieldType(),model.getFieldName()))
                    .append("table.rows[0].getColumnValue(")
                    .append("\""+model.getFieldName()+"\"")
                    .append(")));\n");
        }
        return buffer.toString();
    }

    private static String inferType(String fieldType,String fieldName)
    {
        String result = "";
        if("unsigned bigint".equalsIgnoreCase(fieldType))
        {
           result =  "CommonUtils.getIntValue(";
        }
        if("varchar".equalsIgnoreCase(fieldType))
        {
            result = "CommonUtils.getStringValue(";
        }
        if("datetime".equalsIgnoreCase(fieldType))
        {
            if("update_time".equalsIgnoreCase(fieldName))
            {
                return result;
            }
            result = "CommonUtils.getDateTime2Value(";
        }
        if("tinyint".equalsIgnoreCase(fieldType))
        {
            result =  "CommonUtils.getIntValue(";
        }
        if("bit".equalsIgnoreCase(fieldType))
        {
            result =  "CommonUtils.getBooleanValue(";
        }
        if("decimal".equalsIgnoreCase(fieldType))
        {
            result =  "CommonUtils.getDoubleValue(";
        }
        return result;
    }

    public static String generateMapper(TableModel tableModel, DataBaseModel dataBaseModel) {
        String tableEntityName = tableModel.getCamelName();

        StringBuffer daoStringBuffer = new StringBuffer();



        //package
        daoStringBuffer.append("package "+dataBaseModel.getAppPackageName()+".mapper."+dataBaseModel.getDatabaseName()+";");

        //import
        daoStringBuffer.append("\n\nimport "+dataBaseModel.getAppPackageName()+".ext.domain."+tableEntityName+";\n" +
                "import org.apache.ibatis.annotations.*;\n" +
                "import org.apache.ibatis.jdbc.SQL;\n" +
                "import org.springframework.stereotype.Repository;\n" +
                "import org.springframework.util.Assert;\n" +
                "\n" +
                "import java.util.List;");

        //注释
        daoStringBuffer.append("\n\n/**");
        daoStringBuffer.append("\n * Created by "+dataBaseModel.getDatabaseCreator()+" on "+ DateUtils.Date2String(new Date())+". Copyright © 2016 －2017 深圳布谷鸟信息技术有限公司");
        daoStringBuffer.append("\n *数据库【"+dataBaseModel.getDatabaseName()+"】-表[ "+tableModel.getTableName()+" ]"+tableModel.getTableComment()+"对应的mapper代码");
        daoStringBuffer.append("\n */\n\n@Repository");
        //class
        daoStringBuffer.append("\npublic interface "+ tableEntityName +"Mapper {");



        //insert
        daoStringBuffer.append("\n\n\t/**插入数据 */\n\t@Insert(\"INSERT INTO "+tableModel.getTableName()+" (");

        tableModel.getFields().stream().forEach(item-> {
            if(!"id".equals(item.getFieldName()))
            daoStringBuffer.append(item.getFieldName()).append(",");
        });

        daoStringBuffer.deleteCharAt(daoStringBuffer.length()-1).append(") VALUES(");

        tableModel.getFields().stream().forEach(item-> {
            if(!"id".equals(item.getFieldName()))
            {
                String valueName = item.getCamelFieldName();
                if(Arrays.asList("createAt","updateAt").contains(valueName))
                {
                    daoStringBuffer.append("now(),");
                }else{
                    daoStringBuffer.append("#{"+valueName).append("},");
                }
            }
        });
        daoStringBuffer.deleteCharAt(daoStringBuffer.length()-1).append(")\")\n\tvoid  insert(");

      daoStringBuffer.append(tableEntityName).append(" record );");


      //delete by id

        daoStringBuffer.append("\n\n\t/**按照ID删除数据 */\n\t@Delete(\"DELETE FROM "+tableModel.getTableName()+" WHERE id=#{id}\")\n" +
                "    Long delete(@Param(\"id\") Long id);");

        //update

        //parent_id=#{parentId},type_key=#{typeKey},type_value=#{typeValue},type_desc=#{typeDesc},update_at=now(),creator_id=#{creatorId},system_id=#{systemId}
        daoStringBuffer.append("\n\n\t/**按照ID更新数据 */\n\t@Update(\"UPDATE "+tableModel.getTableName()+" SET ");


        tableModel.getFields().stream().forEach(item-> {
            if(!Arrays.asList("create_at","id").contains(item.getFieldName()))
            {
                String valueName = item.getCamelFieldName();
                if(Arrays.asList("updateAt").contains(valueName))
                {
                    daoStringBuffer.append(" update_at = now(),");
                }else{
                    daoStringBuffer.append(item.getFieldName()+"=#{"+item.getCamelFieldName()+"},");
                }
            }
        });

        daoStringBuffer.deleteCharAt(daoStringBuffer.length()-1).append(" WHERE id=#{id}\")\n" +
                "    Long update("+tableEntityName+" record);");



        //find by id
        daoStringBuffer.append("\n\n\t/**按照ID查询数据 */\n\t@Select(\"SELECT * FROM "+tableModel.getTableName()+" WHERE id=#{id} limit 1\")\n" +
                "    "+tableEntityName+" findById(@Param(\"id\") Long id);");

        daoStringBuffer.append("\n\n\t/**混合条件查询 */\n\t@SelectProvider(type = "+tableEntityName+"Builder.class, method = \"findByParam\")\n" +
                "    List<"+tableEntityName+"> findByParam(@Param(\"param\")"+tableEntityName+" param);" +
                "   \n\n\t/**查询所有 */\n\t @Select(\"SELECT * FROM "+tableModel.getTableName()+"\")" +
                "    List<"+tableEntityName+"> findAll();" +
                " \n\n\t/**按照条件查询得到总数 */\n\t @SelectProvider(type = "+tableEntityName+"Builder.class, method = \"findCountByParam\")\n" +
                "    Integer findCountByParam(@Param(\"param\")"+tableEntityName+" param);\n");



        //inner helper class
        daoStringBuffer.append("\n\n\tclass "+tableEntityName+"Builder{\n\n" +
                "\tprivate static final Logger logger = LoggerFactory.getLogger("+tableEntityName+"Builder.class);\n\n"+

                "\tpublic String findCountByParam(@Param(\"param\") "+tableEntityName+" param) {\n\n" +
                "\t\tSQL sql = new SQL().SELECT(\"count(1)\").FROM(new ReportKfWorkload().getTable()).WHERE(\"1=1\");\n" +
                "\t\tbuildWhereByParam(sql,param);\n" +
                "\t\treturn sql.toString();\n\n\t}\n\n" +

                "\tpublic String findByParam(@Param(\"param\") "+tableEntityName+" param) {\n\n" +
                "\t\tSQL sql = new SQL().SELECT(\"*\").FROM(new ReportKfWorkload().getTable()).WHERE(\"1=1\");\n" +
                "\t\tbuildWhereByParam(sql,param);\n" +
                "\t\treturn sql.toString();\n\n\t}\n" +
                "\n\tpublic void buildWhereByParam(SQL sql, "+tableEntityName+" param) {\n" +
                "\n" +
                "\t\tAssert.notNull(param,\"查询参数不能为空\");");

        tableModel.getFields().stream().forEach(item->{


            daoStringBuffer.append("\n\t\t");
            String fieldType = item.getFieldType().toLowerCase();
            if(Arrays.asList("bigint","int","tinyint","unsigned bigint").contains(fieldType))
            {
                daoStringBuffer.append("if (null!=param.get"+item.getEntityName()+"()  && param.get"+item.getEntityName()+"().intValue()> 0 )");
            }else if(Arrays.asList("varchar","text").contains(fieldType))
            {
                daoStringBuffer.append("if (null!=param.get"+item.getEntityName()+"()  && \"\" != param.get"+item.getEntityName()+"() )");
            }else{
                daoStringBuffer.append("if (null!=param.get"+item.getEntityName()+"() )");
            }
            daoStringBuffer.append("\tsql.AND().WHERE(\""+item.getFieldName()+"=\"+param.get"+item.getEntityName()+"());");


        });

        daoStringBuffer.append("\n\t\tif (null!=param.getMinCreateAt() )\tsql.AND().WHERE(\"create_at>='\"+param.getMinCreateAt().format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\"))+\"'\");\n" +
                "                if (null!=param.getMaxCreateAt() )\tsql.AND().WHERE(\"create_at<'\"+param.getMaxCreateAt().format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\"))+\"'\");");





        daoStringBuffer.append("\n\n\t\tlogger.debug(\"条件查询语句：\" + sql.toString());\n" +
                "        }\n" +
                "    }\n" +
                "\n" +
                "}");
        return daoStringBuffer.toString();
    }
}
